package com.bicon.bdata_service_search.es.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bicon.bdata_service_search.es.bean.AnswerDetailBean;
import com.bicon.bdata_service_search.es.bean.AskAnswerBean;
import com.bicon.bdata_service_search.es.bean.ResultAnswerDetailBean;
import com.bicon.bdata_service_search.es.bean.ResultAskAnswerListBean;
import com.bicon.bdata_service_search.es.common.result.Result;
import com.bicon.bdata_service_search.es.common.result.ResultEnum;
import com.bicon.bdata_service_search.es.common.utils.HTTPSentUtil;
import com.bicon.bdata_service_search.es.common.utils.StringUtil;
import com.bicon.bdata_service_search.es.entities.AccountInfo;
import com.bicon.bdata_service_search.es.entities.QuestionAndAnswer;
import com.bicon.bdata_service_search.es.service.ESAccountInfoService;
import com.bicon.bdata_service_search.es.service.ESQuestionAndAnswerService;
import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.model.crf.CRFLexicalAnalyzer;
import com.hankcs.hanlp.seg.common.Term;
import com.hankcs.hanlp.tokenizer.NotionalTokenizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.*;

/**
 * 描述:
 * controller es
 *
 * @author zhaoyu
 * @email zhaoyu@vv.cc
 * @create 2018-08-23 10:10
 */
@RestController
public class ESController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private ESAccountInfoService esAccountInfoServiceImpl;

    @Autowired
    private ESQuestionAndAnswerService esQuestionAndAnswerServiceImpl;

    @Qualifier("JedisConnectionFactory")
    @Autowired
    JedisConnectionFactory jedisConnectionFactory;

//    @RequestMapping("/esAccountInfo")
//    public String queryAccountInfo(String id, ModelMap modelMap){
//
//        AccountInfo accountInfo = esAccountInfoServiceImpl.queryAccountInfoById(id);
//        modelMap.addAttribute("esAccountInfo",accountInfo);
//        modelMap.addAttribute("test_elastic","Test the elasticsearch");
//
//        return "accountInfo";
//    }

//    @RequestMapping("/esAccountInfoName")
//    public String queryAccountInfoByAccountName(String accountName, ModelMap modelMap) {
//
//        logger.error("this is a test es controller");
//
//        AccountInfo accountInfo = esAccountInfoServiceImpl.queryAccountInfoByName(accountName);
//        modelMap.addAttribute("esAccountInfo", accountInfo);
//        modelMap.addAttribute("test_elastic", "Test the elasticsearch");
//
//        return "accountInfo";
//    }

//    @RequestMapping("/esAccountInfoAll")
//    public String queryAccountInfoAll() {
//
//        logger.error("this is a test es controller");
//
//        Page<AccountInfo> accountInfo = esAccountInfoServiceImpl.findAll();
////        modelMap.addAttribute("esAccountInfo",accountInfo);
////        modelMap.addAttribute("test_elastic","Test the elasticsearch");
//
//        return "accountInfo";
//    }


//    @RequestMapping("/esQuestionAndAnswersAll")
//    public Page<QuestionAndAnswer> queryQuestionAndAnswerAll() {
//
//        logger.error("this is a test es questionAndAnswers");
//
//        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.findAll();
////        modelMap.addAttribute("esAccountInfo",accountInfo);
////        modelMap.addAttribute("test_elastic","Test the elasticsearch");
//
//        return questionAndAnswers;
//    }

    //
//    @GetMapping("/select/{q}")
//    public List<AccountInfo> testSearch(@PathVariable String q) {
//        QueryStringQueryBuilder builder = new QueryStringQueryBuilder(q);
//        Iterable<Book> searchResult = bookDao.search(builder);
//        Iterator<Book> iterator = searchResult.iterator();
//        List<Book> list = new ArrayList<Book>();
//        while (iterator.hasNext()) {
//            list.add(iterator.next());
//        }
//        return list;
//    }
    @RequestMapping(value = "/FindByAskContent", method = RequestMethod.GET)
    public Page<QuestionAndAnswer> queryQuestionAndAnswerFindByAskContent(@RequestParam(value = "askContent", defaultValue = "孟大夫") String ask_content, @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                                          @RequestParam(value = "size", defaultValue = "15") Integer size) {
//        HanlpUtil;
//        Sort sort = new Sort(Sort.Direction.DESC, "askContent");
        String search_str = "";
        try {
            CRFLexicalAnalyzer analyzer = new CRFLexicalAnalyzer();
            logger.info("CRFLexicalAnalyzer: " + analyzer.analyze(ask_content));
            List<Term> search_str_list = NotionalTokenizer.segment(ask_content);
            search_str = StringUtil.ListToString(Collections.singletonList(search_str_list));
            logger.info(search_str);
            logger.info("NotionalTokenizer.segment(ask_content) : " + search_str_list);
            List<String> keywordList = HanLP.extractKeyword(ask_content, 5);
            logger.info("extractKeyword:   " + keywordList);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Pageable pageable = new PageRequest(page, size);
//        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.findByAskContentIsLike("狗咬", pageable);
        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.queryByAskContentLessThan(search_str, pageable);
        return questionAndAnswers;
//        return null;
    }

    @RequestMapping(value = "/FindByAskTitle", method = RequestMethod.GET)
    public Page<QuestionAndAnswer> queryQuestionAndAnswerFindByAskTitle(@RequestParam(value = "askTitle", defaultValue = "孟大夫") String ask_content, @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                                        @RequestParam(value = "size", defaultValue = "15") Integer size) {
//        Sort sort = new Sort(Sort.Direction.DESC, "askContent");
        Pageable pageable = new PageRequest(page, size);
        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.findByAskTitleIsLike(ask_content, pageable);
        return questionAndAnswers;
//        return null;
    }

//    @RequestMapping(value = "/FindByAskContentApi", method = RequestMethod.GET)
//    public String FindByAskContentApi(@RequestParam(value = "askContent", defaultValue = "孟大夫") String ask_content, @RequestParam(value = "page", defaultValue = "0") Integer page,
//                                      @RequestParam(value = "size", defaultValue = "15") Integer size) {
//        String url = "http://192.168.10.181:9200/question_and_answer_index/questionAndAnswer/_search";
//        String url2 = "http://192.168.10.181:9200/question_and_answer_realtime_index/questionAndAnswerRealtime/_search";
//
//
//        List<String> keywordList = HanLP.extractKeyword(ask_content, 5);
////        String search_str = StringUtil.ListToString(Collections.singletonList(keywordList));
//        String search_str = "";
//        for (String str_temp : keywordList) {
//            search_str += (str_temp);
//        }
//        String param = "{\n" +
//                "  \"query\" : { \"match\": { \"askContent\" : " + ask_content + " }},\n" +
//                "\"size\":" + size + ",\"from\":" + page +
//                "}\n";
//        logger.info("query string is " + search_str);
//        String param2 = "{\n" +
//                "  \"query\" :{\n" +
//                "  \t\"multi_match\":{\n" +
//                "  \t\t\"query\":\"" + search_str + "\",\n" +
//                "  \t\t\"fields\":[\"askContent\"],\n" +
//                "  \t\t \"type\": \"phrase\"\n" +
//                "  \t}\n" +
//                "  }\n" +
//                "}";
//        logger.info(param2);
//        String rst = HTTPSentUtil.sendPost(url2, param2);
//        return rst;
//    }

    @RequestMapping(value = "/FindByAskContent2", method = RequestMethod.GET)
    public Page<QuestionAndAnswer> findByAskConent2(@RequestParam(value = "askContent", defaultValue = "孟大夫") String askContent, @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                    @RequestParam(value = "size", defaultValue = "15") Integer size) {
//        Sort sort = new Sort(Sort.Direction.DESC, "askContent");
        Pageable pageable = new PageRequest(page, size);
        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.findByAskContent(askContent, pageable);
        return questionAndAnswers;
//        return null;
    }
//对外提供服务
    @RequestMapping(value = "/getHotSickness", method = RequestMethod.GET)
    public Result getHotSickness() {
        List<String> keysList = new ArrayList<>();
        RedisConnection jedisConnection = jedisConnectionFactory.getConnection();
        Set<byte[]> redisKeys = jedisConnection.keys("illess_top".getBytes());


        Iterator<byte[]> it = redisKeys.iterator();
        while (it.hasNext()) {
            byte[] data = (byte[]) it.next();
            byte[] value = jedisConnection.get(data);
            keysList.add(new String(value, 0, value.length));
        }
        jedisConnection.close();

        List<String> rst = new ArrayList<>();
        for (int i = 0; i < keysList.size(); i++) {
            if (i >= 10) {
                break;
            }
            rst.add(keysList.get(i));
        }
        logger.info("hot words = [" + rst + "]  and size = " + rst.size());
        String rst_str = rst.get(0);
        String[] rst2 = rst_str.split(",");

        return new Result(ResultEnum.SUCCESS.getValue(), ResultEnum.SUCCESS.getMsg(), rst2);
    }

    @RequestMapping(value = "/getAskAnswerList21", method = RequestMethod.GET)
    public Result getAskAnswerList21(@RequestParam(value = "askContent", defaultValue = "孟大夫") String askContent, @RequestParam(value = "page", defaultValue = "0") Integer page,
                                   @RequestParam(value = "size", defaultValue = "15") Integer size) {
        ArrayList<AskAnswerBean> askAnswerBeans = new ArrayList<>();
        AskAnswerBean askAnswerBean = new AskAnswerBean();
        askAnswerBean.setAnswerNum(124);
        askAnswerBean.setAskContent("糖尿病是如何引起的啊");
        askAnswerBean.setAskEsId("40288a0f65a29e800165a2a2e05a4483");
        String[] img = {"http://192.168.10.199/img/20180905/f3e38568b0d611e89c21000c290ff4bd.jpg", "http://192.168.10.199/img/20180905/f3e38568b0d611e89c21000c290ff4bd.jpg"};
        askAnswerBean.setDoctorImg(img);
        askAnswerBeans.add(askAnswerBean);


        askAnswerBean.setAnswerNum(526);
        askAnswerBean.setAskContent("糖尿病是如何引起的啊2");
        askAnswerBean.setAskEsId("40288a0f65a29e800165a2a2e05a4483");
        String[] img2 = {"http://192.168.10.199/img/20180905/f3e38568b0d611e89c21000c290ff4bd.jpg", "http://192.168.10.199/img/20180905/f3e38568b0d611e89c21000c290ff4bd.jpg"};
        askAnswerBean.setDoctorImg(img2);
        askAnswerBeans.add(askAnswerBean);
        ResultAskAnswerListBean resultAskAnswerListBean = new ResultAskAnswerListBean();
        resultAskAnswerListBean.setRecords(askAnswerBeans);
        resultAskAnswerListBean.setCurrent(41);
        resultAskAnswerListBean.setSize(10);
        resultAskAnswerListBean.setTotal(410);
        return new Result(ResultEnum.SUCCESS.getValue(), ResultEnum.SUCCESS.getMsg(), resultAskAnswerListBean);

    }

    @RequestMapping(value = "/getAskAnswerDetail2", method = RequestMethod.GET)
    public Result getAskAnswerDetail2(@RequestParam(value = "askContent", defaultValue = "孟大夫") String askContent, @RequestParam(value = "page", defaultValue = "0") Integer page,
                                     @RequestParam(value = "size", defaultValue = "15") Integer size) {
        ResultAnswerDetailBean resultAnswerDetailBean = new ResultAnswerDetailBean();
        AnswerDetailBean answerDetailBean = new AnswerDetailBean();
        answerDetailBean.setDoctor_img("http://192.168.10.199/img/20180905/f3e38568b0d611e89c21000c290ff4bd.jpg");
        answerDetailBean.setAnswer_time("2018-08-16 09:16:58");
        answerDetailBean.setAnswer_content("您好，糖尿病临床上以高血糖为主要特点，典型病例可出现多尿、多饮、多食、消瘦等表现，即“三多一少”症状。控制总热能是糖尿病饮食治疗的首要原则。。。长期坚持规范治疗是最重要的，包括：控制饮食，坚持适量运动锻炼，合理用药，糖尿病监测。当前医学专家则提倡高碳水化合物量，降低脂肪比例，控制蛋白质摄入的饮食结构，对改善血糖耐量有较好的效果。");
        answerDetailBean.setDoctor_dep("内科");
        answerDetailBean.setDoctor_good("感冒");
        answerDetailBean.setDoctor_name("张三");
        answerDetailBean.setDoctor_hos("三秦医院");
        answerDetailBean.setDoctor_pos("副主任");
        ArrayList<AnswerDetailBean> answerDetailBeans = new ArrayList<>();
        resultAnswerDetailBean.setRecords(answerDetailBeans);
        resultAnswerDetailBean.setAskAge("18");
        resultAnswerDetailBean.setAskContent("糖尿病是如何引起的啊");
        resultAnswerDetailBean.setAskDepartment("糖尿病");
        resultAnswerDetailBean.setAskEsId("40288a0f65a29e800165a2a2e05a4483");
        resultAnswerDetailBean.setAskNum(1);
        resultAnswerDetailBean.setAskSex("男");
        resultAnswerDetailBean.setAskTime("2018-08-16 09:16:58");
        resultAnswerDetailBean.setPage(0);
        resultAnswerDetailBean.setSize(10);
        answerDetailBeans.add(answerDetailBean);


        return new Result(ResultEnum.SUCCESS.getValue(), ResultEnum.SUCCESS.getMsg(), resultAnswerDetailBean);

    }
    //对外提供服务
    @RequestMapping(value = "/getAskAnswerList", method = RequestMethod.GET)
    public Result getAskAnswerList(@RequestParam(value = "askContent", defaultValue = "孟大夫") String askContent, @RequestParam(value = "page", defaultValue = "0") Integer page,
                                    @RequestParam(value = "size", defaultValue = "15") Integer size) {
        Pageable pageable = new PageRequest(page, size);
//        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.queryByAskContentLessThan(ask_content, pageable);
//        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.findByAskContent(askContent, pageable);
        ResultAskAnswerListBean resultAskAnswerListBean = new ResultAskAnswerListBean();
//        Pageable pageable = new PageRequest(page, size);
        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.findByAskContent(askContent, pageable);
//        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.esFind1(askContent, pageable);
        List<QuestionAndAnswer> questionAndAnswerList = questionAndAnswers.getContent();

        ArrayList<AskAnswerBean> askAnswerBeans = new ArrayList<>();

        for (QuestionAndAnswer temp : questionAndAnswerList) {
            AskAnswerBean askAnswerBean = new AskAnswerBean();
            askAnswerBean.setAskEsId(temp.getAskContentMd5());
            askAnswerBean.setAskContent(temp.getAskContent());
            String a = temp.getAnswers();
            int answer_num = JSON.parseArray(a).size();
            askAnswerBean.setAnswerNum(answer_num);
            askAnswerBean.setDoctorImg(getDoctorImgFromAnswer(temp.getAnswers()));
            askAnswerBeans.add(askAnswerBean);
        }
        resultAskAnswerListBean.setRecords(askAnswerBeans);
        resultAskAnswerListBean.setCurrent(page);
        resultAskAnswerListBean.setSize(size);
        resultAskAnswerListBean.setTotal((int) questionAndAnswers.getTotalElements());
        return new Result(ResultEnum.SUCCESS.getValue(), ResultEnum.SUCCESS.getMsg(), resultAskAnswerListBean);
    }
    //对外提供服务
    @RequestMapping(value = "/getAskAnswerList2_backup", method = RequestMethod.GET)
    public Result getAskAnswerList2_backup(@RequestParam(value = "askContent", defaultValue = "孟大夫") String askContent, @RequestParam(value = "page", defaultValue = "0") Integer page,
                                   @RequestParam(value = "size", defaultValue = "15") Integer size) {
        Pageable pageable = new PageRequest(page, size);
        ResultAskAnswerListBean resultAskAnswerListBean = new ResultAskAnswerListBean();
        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.esFind1(askContent, pageable);
        List<QuestionAndAnswer> questionAndAnswerList = questionAndAnswers.getContent();

        ArrayList<AskAnswerBean> askAnswerBeans = new ArrayList<>();

        for (QuestionAndAnswer temp : questionAndAnswerList) {
            AskAnswerBean askAnswerBean = new AskAnswerBean();
            askAnswerBean.setAskEsId(temp.getAskContentMd5());
            askAnswerBean.setAskContent(temp.getAskContent());
            String a = temp.getAnswers();
            int answer_num = JSON.parseArray(a).size();
            askAnswerBean.setAnswerNum(answer_num);
            askAnswerBean.setDoctorImg(getDoctorImgFromAnswer(temp.getAnswers()));
            askAnswerBeans.add(askAnswerBean);
        }
        resultAskAnswerListBean.setRecords(askAnswerBeans);
        resultAskAnswerListBean.setCurrent(page);
        resultAskAnswerListBean.setSize(size);
        resultAskAnswerListBean.setTotal((int) questionAndAnswers.getTotalElements());
        return new Result(ResultEnum.SUCCESS.getValue(), ResultEnum.SUCCESS.getMsg(), resultAskAnswerListBean);
    }

    //    /getAskAnswerDetail?askEsId=问题ID
    //对外提供服务
    @RequestMapping(value = "/getAskAnswerDetail_backup", method = RequestMethod.GET)
    public Result getAskAnswerDetail_backup(@RequestParam(value = "askEsId", defaultValue = "") String askEsId){
        String esId = askEsId;
        if(StringUtils.isEmpty(esId)){
            return new Result(ResultEnum.FAIL.getValue(), ResultEnum.FAIL.getMsg(), "please input esId");
        }
        int size = 1;
        int page = 0;
        Pageable pageable = new PageRequest(0, 2);
        ResultAnswerDetailBean resultAnswerDetailBean = new ResultAnswerDetailBean();
        ArrayList<AnswerDetailBean> answerDetailBeans;
        Page<QuestionAndAnswer> questionAndAnswers = esQuestionAndAnswerServiceImpl.getByAskContentMd5Is(esId,pageable);

        if(0 == questionAndAnswers.getTotalElements()){
            return new Result(ResultEnum.FAIL.getValue(), ResultEnum.FAIL.getMsg(), "[ id :"+esId+" ] is not in es");
        }
        List<QuestionAndAnswer> questionAndAnswers_list = questionAndAnswers.getContent();
        QuestionAndAnswer questionAndAnswer_md5= questionAndAnswers_list.get(0);
//        ResultAnswerDetailBean resultAnswerDetailBean = new ResultAnswerDetailBean();
//        AnswerDetailBean answerDetailBean = new AnswerDetailBean();
        String answer = questionAndAnswer_md5.getAnswers();

        answerDetailBeans =getAnswerDetail(answer);
        resultAnswerDetailBean.setSize(size);
        resultAnswerDetailBean.setPage(page);
        resultAnswerDetailBean.setAskTime(questionAndAnswer_md5.getAskTime());
        resultAnswerDetailBean.setAskSex(questionAndAnswer_md5.getAskSex());
        resultAnswerDetailBean.setAskAge(questionAndAnswer_md5.getAskAge());
        resultAnswerDetailBean.setAskEsId(questionAndAnswer_md5.getAskContentMd5());
        resultAnswerDetailBean.setSourceWeb(questionAndAnswer_md5.getSourceWeb());
        resultAnswerDetailBean.setAskContent(questionAndAnswer_md5.getAskContent());
        resultAnswerDetailBean.setAskDepartment(questionAndAnswer_md5.getAskDepartment());
        resultAnswerDetailBean.setAskNum(answerDetailBeans.size());
        resultAnswerDetailBean.setRecords(answerDetailBeans);
//        answerDetailBean.setDoctor_name();
        return new Result(ResultEnum.SUCCESS.getValue(), ResultEnum.SUCCESS.getMsg(), resultAnswerDetailBean);
    }

    private String[] getDoctorImgFromAnswer(String answer) {
        JSONArray answer_json = JSON.parseArray(answer);
        int json_lenth = answer_json.size();
        List<String> rst = new ArrayList<>();
        for (int i = 0; i < json_lenth; i++) {
            JSONObject answer_temp = answer_json.getJSONObject(i);
            String img_str = (String) answer_temp.get("doctor_img");
            if(StringUtils.isEmpty(img_str)){
                continue;
            }
            rst.add(img_str);
        }
        return rst.toArray(new String[rst.size()]);
    }

    private ArrayList<AnswerDetailBean> getAnswerDetail (String answer){
        JSONArray answer_json = JSON.parseArray(answer);
        int json_lenth = answer_json.size();
        List<String> rst = new ArrayList<>();
        ArrayList<AnswerDetailBean> answerDetailBeans = new ArrayList<>();

        for (int i = 0; i < json_lenth; i++) {
            AnswerDetailBean answerDetailBean = new AnswerDetailBean();
            JSONObject answer_temp = answer_json.getJSONObject(i);
//            String img_str = (String) answer_temp.get("doctor_img");
            answerDetailBean.setDoctor_name((String) answer_temp.get("doctor_name"));
            answerDetailBean.setDoctor_pos((String) answer_temp.get("doctor_pos"));
            answerDetailBean.setDoctor_hos((String) answer_temp.get("doctor_hos"));
            answerDetailBean.setDoctor_good((String)answer_temp.get("doctor_good"));
            answerDetailBean.setDoctor_dep((String)answer_temp.get("doctor_dep"));
            answerDetailBean.setDoctor_img((String) answer_temp.get("doctor_img"));
            answerDetailBean.setAnswer_time((String) answer_temp.get("answer_time"));
            answerDetailBean.setAnswer_content((String) answer_temp.get("answer_content"));
            answerDetailBeans.add(answerDetailBean);
        }
        return answerDetailBeans;
    }
}